package edu.csu.smartpark.controller;

import edu.csu.smartpark.model.DO.UserDO;
import edu.csu.smartpark.model.DTO.UserDTO;
import edu.csu.smartpark.model.common.BusinessException;
import edu.csu.smartpark.model.common.MsgEntity;
import edu.csu.smartpark.service.LoginService;
import edu.csu.smartpark.util.Constants;
import edu.csu.smartpark.util.JwtUtil;
import edu.csu.smartpark.util.PhoneCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private PhoneCodeUtil phoneCodeUtil;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/login")
    public MsgEntity login(UserDTO userDTO, @RequestParam("login_type") String loginType) throws BusinessException {
        if (userDTO.getUsername() == "" || userDTO.getPassword()==""){
            throw new BusinessException(BusinessException.LOGINERROR, "username or password can not be empty");
        }
        UserDO userDO = loginService.getUserByPhone(userDTO.getUsername());
        if (userDO == null){
            throw new BusinessException(BusinessException.LOGINERROR, "user is not exist, please register first");
        }

        if (loginType == Constants.PhonePassword){
            log.info("User is logging in. Username:{} , Password:{}", userDTO.getUsername(), userDTO.getPassword());
            String encryptPassword = encryptPassword(userDTO.getPassword());
            if (!userDO.getEncryptPassword().equals(encryptPassword)){
                throw new BusinessException(BusinessException.LOGINERROR, "username or password is wrong");
            }
        }else {
            log.info("User is logging in. Username:{} , PhoneCode:{}", userDTO.getUsername(), userDTO.getPassword());
            if (!phoneCodeUtil.getCode(userDTO.getUsername()).equals(userDTO.getPassword())){
                throw new BusinessException(BusinessException.LOGINERROR, "phone code is wrong");
            }
        }
        String sessionID = generateSessionID(userDO.getUsername(),userDO.getRoles());
        return new MsgEntity("SUCCESS", MsgEntity.SUCCESS, sessionID);
    }

    @PostMapping("/register")
    public MsgEntity register(UserDTO userDTO) throws BusinessException{
        if (loginService.isPhoneExist(userDTO.getPhone())){
            throw new BusinessException(BusinessException.REGISTERERROR,"this phone number has been registered");
        }

        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userDTO, userDO);
        List<String> roles = new ArrayList<>();
        roles.add(Constants.CommonUser);
        userDO.setRoles(roles);
        userDO.setEncryptPassword(userDTO.getPassword());
        int id = loginService.register(userDO);
        if (id <= 0) {
            throw new BusinessException(BusinessException.REGISTERERROR, "server internal error, register fail");
        }
        String sessionID = generateSessionID(userDO.getUsername(), userDO.getRoles());
        return new MsgEntity("SUCCESS", MsgEntity.SUCCESS, sessionID);
    }

    @GetMapping("/getCode")
    public String getPhoneCode(String phone){
        String code = phoneCodeUtil.sendCode(phone);
        return code;
    }

    /*
    * @Description: 根据用户信息生成ID返回给前端，用这个标识用户状态
    * @Author: LZY
    * @Date: 2021/4/20 15:03
    * @Params:
    * @Return:
    */
    private String generateSessionID(String username, List<String> roles) {
        Map<String, Object> chaim = new HashMap<>();
        chaim.put("username", username);
        chaim.put("role", roles);
        // 登录状态过去时间为1天
        return jwtUtil.encode(username, 24 * 60 * 60 * 1000, chaim);
    }

    private String encryptPassword(String password){
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] md5Bytes =  messageDigest.digest(password.getBytes());
            return md5Bytes.toString();
        }catch (Exception e){
            log.error("[smart park server]password encrypt fail");
            return "";
        }
    }
}
